package com.tyqx.hashchainbiz.controller.mongodb;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.stream.JsonReader;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.GridFSFindIterable;
import com.mongodb.client.gridfs.model.GridFSFile;
import com.mongodb.client.model.Filters;
import com.tyqx.hashchainbean.module.JZTAttachmentBusiness;
import com.tyqx.hashchainbean.module.JZTCodeCirculationAttachment;
import com.tyqx.hashchainbean.module.JZTGS1Attachment;
import com.tyqx.hashchainbean.module.JZTLogistics;
import com.tyqx.hashchainbean.vo.ImageAttachementVO;
import com.tyqx.hashchainbean.vo.MongoDbInfoVO;
import com.tyqx.hashchainutil.common.mongodb.ImagePathHashValueUtil;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.hyperledger.fabric.sdk.security.CryptoPrimitives;
import sun.misc.BASE64Encoder;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MongoDBGridFSUtil {


    public static MongoDbInfoAndObjectIdVO getMongoDBGridFSToStringOne(GridFSBucket gridFSFilesBucket) throws IOException {
        int i = 0;
        MongoCursor mongoCursor = gridFSFilesBucket.find(Filters.eq("filename", "mongodb-jzt-attachment-businesss-0")).iterator();
        while (mongoCursor.hasNext()) {
            mongoCursor.next();
            i++;
        }

        Random random = new Random();

        int skip = 0;
        if (i > 0) {
            skip = random.nextInt(i);
            ObjectId objectId = gridFSFilesBucket.find(Filters.eq("filename", "mongodb-jzt-attachment-businesss-0")).skip(skip).first().getObjectId();

            GridFSDownloadStream downloadStream = gridFSFilesBucket.openDownloadStream(objectId);
            JsonReader jsonReader = new JsonReader(new InputStreamReader(downloadStream));
            String hashValue = "";
            MongoDbInfoVO mongoDbInfoVO = new MongoDbInfoVO();
            List<JZTAttachmentBusiness> attachmentBusinessInfoList = new ArrayList<>();
            List<JZTLogistics> logisticsInfoList = new ArrayList<>();
            String infoTableName = "";

            jsonReader.beginObject();
            int offset = 0;
            while (jsonReader.hasNext()) {
                String name = jsonReader.nextName();
                if (name.equals("hashValue")) {
                    hashValue = jsonReader.nextString();
                    mongoDbInfoVO.setHashValue(hashValue);
                } else if (name.equals("infoTableName")) {
                    infoTableName = jsonReader.nextString();
                } else if (name.equals("infoList")) {
                    jsonReader.beginArray();
                    while (jsonReader.hasNext()) {
                        jsonReader.beginObject();
                        String attachment = "";
                        String businessOrderNumber = "";
                        String userName = "";
                        JZTAttachmentBusiness jztAttachmentBusiness = new JZTAttachmentBusiness();
                        while (jsonReader.hasNext()) {
                            String name1 = jsonReader.nextName();
                            if (name1.equals("attachment")) {
                                attachment = jsonReader.nextString();
                                jztAttachmentBusiness.setAttachment(attachment);
                            } else if (name1.equals("businessOrderNumber")) {
                                businessOrderNumber = jsonReader.nextString();
                                jztAttachmentBusiness.setBusinessOrderNumber(businessOrderNumber);
                            } else if (name1.equals("userName")) {
                                userName = jsonReader.nextString();
                                jztAttachmentBusiness.setUserName(userName);
                            }
                        }
                        jsonReader.endObject();
                        jztAttachmentBusiness.setOffset(offset);
                        jztAttachmentBusiness.setObjectId(objectId.toString());
                        offset++;
                        attachmentBusinessInfoList.add(jztAttachmentBusiness);
                    }
                    jsonReader.endArray();
                }
            }
            jsonReader.endObject();

            mongoDbInfoVO.setInfoList(attachmentBusinessInfoList);
            mongoDbInfoVO.setInfoTableName("jztAttachmentBusinessList");
            MongoDbInfoAndObjectIdVO mongoDbInfoAndObjectIdVO = new MongoDbInfoAndObjectIdVO();
            mongoDbInfoAndObjectIdVO.setMongoDbInfoVO(mongoDbInfoVO);
            mongoDbInfoAndObjectIdVO.setObjectId(objectId);
            return mongoDbInfoAndObjectIdVO;
        }
        return null;


    }


    public static JZTAttachmentBusiness getJZTAttachmentBusinessByObjectIdAndOffset(GridFSBucket gridFSFilesBucket, ObjectId objectId, Integer offset) throws IOException {
        GridFSDownloadStream downloadStream = gridFSFilesBucket.openDownloadStream(objectId);
        JsonReader jsonReader = new JsonReader(new InputStreamReader(downloadStream));
        String hashValue = "";
        MongoDbInfoVO mongoDbInfoVO = new MongoDbInfoVO();
        List<JZTAttachmentBusiness> attachmentBusinessInfoList = new ArrayList<>();
        List<JZTLogistics> logisticsInfoList = new ArrayList<>();
        String infoTableName = "";

        jsonReader.beginObject();
        int i = 0;
        while (jsonReader.hasNext()) {
            String name = jsonReader.nextName();
            if (name.equals("hashValue")) {
                hashValue = jsonReader.nextString();
                mongoDbInfoVO.setHashValue(hashValue);
            } else if (name.equals("infoTableName")) {
                infoTableName = jsonReader.nextString();
            } else if (name.equals("infoList")) {
                jsonReader.beginArray();
                while (jsonReader.hasNext()) {
                    jsonReader.beginObject();
                    String attachment = "";
                    String businessOrderNumber = "";
                    String userName = "";
                    JZTAttachmentBusiness jztAttachmentBusiness = new JZTAttachmentBusiness();
                    while (jsonReader.hasNext()) {
                        String name1 = jsonReader.nextName();
                        if (name1.equals("attachment")) {
                            attachment = jsonReader.nextString();
                            jztAttachmentBusiness.setAttachment(attachment);
                        } else if (name1.equals("businessOrderNumber")) {
                            businessOrderNumber = jsonReader.nextString();
                            jztAttachmentBusiness.setBusinessOrderNumber(businessOrderNumber);
                        } else if (name1.equals("userName")) {
                            userName = jsonReader.nextString();
                            jztAttachmentBusiness.setUserName(userName);
                        }
                    }
                    jsonReader.endObject();
                    jztAttachmentBusiness.setOffset(offset);
                    jztAttachmentBusiness.setObjectId(objectId.toString());
                    if (i == offset) {
                        return jztAttachmentBusiness;
                    }
                    i++;
                }
                jsonReader.endArray();
            }
        }
        jsonReader.endObject();


        return null;
    }


    public static List<JZTAttachmentBusiness> getJZTAttachmentBusinessByObjectId(GridFSBucket gridFSFilesBucket, ObjectId objectId) throws IOException {
        GridFSDownloadStream downloadStream = gridFSFilesBucket.openDownloadStream(objectId);
        JsonReader jsonReader = new JsonReader(new InputStreamReader(downloadStream));
        String hashValue = "";
        MongoDbInfoVO mongoDbInfoVO = new MongoDbInfoVO();
        List<JZTAttachmentBusiness> attachmentBusinessInfoList = new ArrayList<>();
        List<JZTLogistics> logisticsInfoList = new ArrayList<>();
        String infoTableName = "";

        jsonReader.beginObject();
        while (jsonReader.hasNext()) {
            String name = jsonReader.nextName();
            if (name.equals("hashValue")) {
                hashValue = jsonReader.nextString();
                mongoDbInfoVO.setHashValue(hashValue);
            } else if (name.equals("infoTableName")) {
                infoTableName = jsonReader.nextString();
            } else if (name.equals("infoList")) {
                jsonReader.beginArray();
                while (jsonReader.hasNext()) {
                    jsonReader.beginObject();
                    String attachment = "";
                    String businessOrderNumber = "";
                    String userName = "";
                    JZTAttachmentBusiness jztAttachmentBusiness = new JZTAttachmentBusiness();
                    while (jsonReader.hasNext()) {
                        String name1 = jsonReader.nextName();
                        if (name1.equals("attachment")) {
                            attachment = jsonReader.nextString();
                            jztAttachmentBusiness.setAttachment(attachment);
                        } else if (name1.equals("businessOrderNumber")) {
                            businessOrderNumber = jsonReader.nextString();
                            jztAttachmentBusiness.setBusinessOrderNumber(businessOrderNumber);
                        } else if (name1.equals("userName")) {
                            userName = jsonReader.nextString();
                            jztAttachmentBusiness.setUserName(userName);
                        }
                    }
                    jsonReader.endObject();
                    attachmentBusinessInfoList.add(jztAttachmentBusiness);
                }
                jsonReader.endArray();
            }
        }
        jsonReader.endObject();
        return attachmentBusinessInfoList;
    }


    public static List<JZTAttachmentBusiness> getJZTAttachmentFile(GridFSBucket gridFSFilesBucket) throws IOException, Exception {
        CryptoPrimitives suite = new CryptoPrimitives();
        suite.init();
        int i = 0;
        MongoCursor mongoCursor = gridFSFilesBucket.find(Filters.eq("filename", "mongodb-jzt-attachment-businesss-0")).iterator();
        while (mongoCursor.hasNext()) {
            mongoCursor.next();
            i++;
        }
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                .create();
        Random random = new Random();

        int pageSize = 1000;

        int skip = 0;
        if (i > 0) {
            GridFSFindIterable gridFSFindIterable;
            if (i<=pageSize) {
                gridFSFindIterable=gridFSFilesBucket.find(Filters.eq("filename", "mongodb-jzt-attachment-businesss-0")).limit(pageSize);
            }else{
                skip = random.nextInt(i-pageSize);
                gridFSFindIterable=gridFSFilesBucket.find(Filters.eq("filename", "mongodb-jzt-attachment-businesss-0")).skip(skip).limit(pageSize);
            }


            MongoCursor<GridFSFile> mongoCursor1 = gridFSFindIterable.iterator();

            List<JZTAttachmentBusiness> jztAttachmentBusinessList = new ArrayList<>();

            while (mongoCursor1.hasNext()) {
                GridFSFile gridFSFile = mongoCursor1.next();
                Document document = gridFSFile.getMetadata();
                Document documentMap=(Document)document.get("documentMap");
                String userName=documentMap.getString("userName");
                String businessOrderNumber = documentMap.getString("businessOrderNumber");
                Integer offset=documentMap.getInteger("offset");
                String contentType=documentMap.getString("contentType");
                ObjectId objectId = gridFSFile.getObjectId();

                GridFSDownloadStream downloadStream = gridFSFilesBucket.openDownloadStream(objectId);
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                gridFSFilesBucket.downloadToStream(objectId, byteArrayOutputStream);

                //String attachment = byteArrayOutputStream.toString();

                byte[] fileBytes=byteArrayOutputStream.toByteArray();
                BASE64Encoder base64Encoder = new BASE64Encoder();

                String base64EncoderImg = "data:" + contentType + ";base64," + base64Encoder.encode(fileBytes);

                base64EncoderImg.replaceAll("[\\s*\t\n\r]", "");


                //String attachmentHashValue = ImagePathHashValueUtil.getHashValue(attachment, suite);

                String attachmentHashValue = ImagePathHashValueUtil.getHashValue(base64EncoderImg, suite);

                JZTAttachmentBusiness jztAttachmentBusiness = new JZTAttachmentBusiness();
                jztAttachmentBusiness.setUserName(userName);
                jztAttachmentBusiness.setBusinessOrderNumber(businessOrderNumber);
                jztAttachmentBusiness.setAttachment(attachmentHashValue);
                jztAttachmentBusiness.setObjectId(objectId.toHexString());
                jztAttachmentBusiness.setOffset(offset);
                jztAttachmentBusiness.setContentType(contentType);
                jztAttachmentBusinessList.add(jztAttachmentBusiness);
            }
            return jztAttachmentBusinessList;
        }
        return null;
    }


    public static List<JZTCodeCirculationAttachment> getJZTCodeCirculationAttachmentFile(GridFSBucket gridFSFilesBucket) throws IOException, Exception {
        CryptoPrimitives suite = new CryptoPrimitives();
        suite.init();
        int i = 0;
        MongoCursor mongoCursor = gridFSFilesBucket.find(Filters.eq("filename", "mongodb-jzt-code-circulation-attachment-0")).iterator();
        while (mongoCursor.hasNext()) {
            mongoCursor.next();
            i++;
        }
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                .create();
        Random random = new Random();

        int pageSize = 1000;

        int skip = 0;
        if (i > 0) {
            GridFSFindIterable gridFSFindIterable;
            if (i<=pageSize) {
                gridFSFindIterable=gridFSFilesBucket.find(Filters.eq("filename", "mongodb-jzt-code-circulation-attachment-0")).limit(pageSize);
            }else{
                skip = random.nextInt(i-pageSize);
                gridFSFindIterable=gridFSFilesBucket.find(Filters.eq("filename", "mongodb-jzt-code-circulation-attachment-0")).skip(skip).limit(pageSize);
            }


            MongoCursor<GridFSFile> mongoCursor1 = gridFSFindIterable.iterator();

            List<JZTCodeCirculationAttachment> jztCodeCirculationAttachmentList = new ArrayList<>();

            while (mongoCursor1.hasNext()) {
                GridFSFile gridFSFile = mongoCursor1.next();
                Document document = gridFSFile.getMetadata();
                Document documentMap=(Document)document.get("documentMap");
                String userName=documentMap.getString("userName");
                String businessOrderNumber = documentMap.getString("businessOrderNumber");
                Integer offset=documentMap.getInteger("offset");
                String contentType=documentMap.getString("contentType");
                ObjectId objectId = gridFSFile.getObjectId();

                GridFSDownloadStream downloadStream = gridFSFilesBucket.openDownloadStream(objectId);
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                gridFSFilesBucket.downloadToStream(objectId, byteArrayOutputStream);

                byte[] fileBytes=byteArrayOutputStream.toByteArray();
                BASE64Encoder base64Encoder = new BASE64Encoder();

                String base64EncoderImg = "data:" + contentType + ";base64," + base64Encoder.encode(fileBytes);

                base64EncoderImg.replaceAll("[\\s*\t\n\r]", "");


                //String attachmentHashValue = ImagePathHashValueUtil.getHashValue(attachment, suite);

                String attachmentHashValue = ImagePathHashValueUtil.getHashValue(base64EncoderImg, suite);

                JZTCodeCirculationAttachment jztCodeCirculationAttachment=new JZTCodeCirculationAttachment();
                jztCodeCirculationAttachment.setAttachment(attachmentHashValue);
                jztCodeCirculationAttachment.setUserName(userName);
                jztCodeCirculationAttachment.setBusinessOrderNumber(businessOrderNumber);
                jztCodeCirculationAttachment.setObjectId(objectId.toHexString());
                jztCodeCirculationAttachment.setOffset(offset);
                jztCodeCirculationAttachment.setContentType(contentType);
                jztCodeCirculationAttachmentList.add(jztCodeCirculationAttachment);
            }
            return jztCodeCirculationAttachmentList;
        }
        return null;
    }


    public static List<JZTGS1Attachment> getJZTGS1AttachmentFile(GridFSBucket gridFSFilesBucket) throws IOException, Exception {
        CryptoPrimitives suite = new CryptoPrimitives();
        suite.init();
        int i = 0;
        MongoCursor mongoCursor = gridFSFilesBucket.find(Filters.eq("filename", "mongodb-jzt-GS1-attachment-0")).iterator();
        while (mongoCursor.hasNext()) {
            mongoCursor.next();
            i++;
        }
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                .create();
        Random random = new Random();

        int pageSize = 1000;

        int skip = 0;
        if (i > 0) {
            GridFSFindIterable gridFSFindIterable;
            if (i<=pageSize) {
                gridFSFindIterable=gridFSFilesBucket.find(Filters.eq("filename", "mongodb-jzt-GS1-attachment-0")).limit(pageSize);
            }else{
                skip = random.nextInt(i-pageSize);
                gridFSFindIterable=gridFSFilesBucket.find(Filters.eq("filename", "mongodb-jzt-GS1-attachment-0")).skip(skip).limit(pageSize);
            }


            MongoCursor<GridFSFile> mongoCursor1 = gridFSFindIterable.iterator();

            List<JZTGS1Attachment> jztgs1AttachmentList = new ArrayList<>();

            while (mongoCursor1.hasNext()) {
                GridFSFile gridFSFile = mongoCursor1.next();
                Document document = gridFSFile.getMetadata();
                Document documentMap=(Document)document.get("documentMap");
                String userName=documentMap.getString("userName");
                String ssccCode = documentMap.getString("ssccCode");
                Integer offset=documentMap.getInteger("offset");
                String contentType=documentMap.getString("contentType");
                ObjectId objectId = gridFSFile.getObjectId();

                GridFSDownloadStream downloadStream = gridFSFilesBucket.openDownloadStream(objectId);
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                gridFSFilesBucket.downloadToStream(objectId, byteArrayOutputStream);
                byte[] fileBytes=byteArrayOutputStream.toByteArray();
                BASE64Encoder base64Encoder = new BASE64Encoder();

                String base64EncoderImg = "data:" + contentType + ";base64," + base64Encoder.encode(fileBytes);

                base64EncoderImg.replaceAll("[\\s*\t\n\r]", "");


                //String attachmentHashValue = ImagePathHashValueUtil.getHashValue(attachment, suite);

                String attachmentHashValue = ImagePathHashValueUtil.getHashValue(base64EncoderImg, suite);

                JZTGS1Attachment jztgs1Attachment=new JZTGS1Attachment();
                jztgs1Attachment.setUserName(userName);
                jztgs1Attachment.setAttachment(attachmentHashValue);
                jztgs1Attachment.setSsccCode(ssccCode);
                jztgs1Attachment.setObjectId(objectId.toHexString());
                jztgs1Attachment.setOffset(offset);
                jztgs1Attachment.setContentType(contentType);
                jztgs1AttachmentList.add(jztgs1Attachment);
            }
            return jztgs1AttachmentList;
        }
        return null;
    }

   /* public static List<JZTGS1Attachment> getAttachmentFile(GridFSBucket gridFSFilesBucket,String fileValue) throws IOException, Exception {
        CryptoPrimitives suite = new CryptoPrimitives();
        suite.init();
        int i = 0;
        MongoCursor mongoCursor = gridFSFilesBucket.find(Filters.eq("filename", fileValue)).iterator();
        while (mongoCursor.hasNext()) {
            mongoCursor.next();
            i++;
        }
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                .create();
        Random random = new Random();

        int pageSize = 1000;

        int skip = 0;
        if (i > 0) {
            GridFSFindIterable gridFSFindIterable;
            if (i<=pageSize) {
                gridFSFindIterable=gridFSFilesBucket.find(Filters.eq("filename", fileValue)).limit(pageSize);
            }else{
                skip = random.nextInt(i-pageSize);
                gridFSFindIterable=gridFSFilesBucket.find(Filters.eq("filename", fileValue)).skip(skip).limit(pageSize);
            }


            MongoCursor<GridFSFile> mongoCursor1 = gridFSFindIterable.iterator();

            List<JZTGS1Attachment> jztgs1AttachmentList = new ArrayList<>();

            while (mongoCursor1.hasNext()) {
                GridFSFile gridFSFile = mongoCursor1.next();
                Document document = gridFSFile.getMetadata();
                Document documentMap=(Document)document.get("documentMap");

                ObjectId objectId = gridFSFile.getObjectId();

                GridFSDownloadStream downloadStream = gridFSFilesBucket.openDownloadStream(objectId);
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                gridFSFilesBucket.downloadToStream(objectId, byteArrayOutputStream);
                byte[] fileBytes=byteArrayOutputStream.toByteArray();
                BASE64Encoder base64Encoder = new BASE64Encoder();

                String base64EncoderImg = "data:" + contentType + ";base64," + base64Encoder.encode(fileBytes);

                base64EncoderImg.replaceAll("[\\s*\t\n\r]", "");


                //String attachmentHashValue = ImagePathHashValueUtil.getHashValue(attachment, suite);

                String attachmentHashValue = ImagePathHashValueUtil.getHashValue(base64EncoderImg, suite);

                JZTGS1Attachment jztgs1Attachment=new JZTGS1Attachment();
                jztgs1Attachment.setUserName(userName);
                jztgs1Attachment.setAttachment(attachmentHashValue);
                jztgs1Attachment.setSsccCode(ssccCode);
                jztgs1Attachment.setObjectId(objectId.toHexString());
                jztgs1Attachment.setOffset(offset);
                jztgs1Attachment.setContentType(contentType);
                jztgs1AttachmentList.add(jztgs1Attachment);
            }
            return jztgs1AttachmentList;
        }
        return null;
    }*/


    public static ImageAttachementVO getJZTAttachmentByObjectId(GridFSBucket gridFSFilesBucket, ObjectId objectId,String contentType) throws IOException {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            gridFSFilesBucket.downloadToStream(objectId, byteArrayOutputStream);

            byte[] fileBytes=byteArrayOutputStream.toByteArray();
            BASE64Encoder base64Encoder = new BASE64Encoder();

            String base64EncoderImg = "data:" + contentType + ";base64," + base64Encoder.encode(fileBytes);

            base64EncoderImg.replaceAll("[\\s*\t\n\r]", "");

            //String attachment = byteArrayOutputStream.toString();
            ImageAttachementVO imageAttachementVO=new ImageAttachementVO();
            //imageAttachementVO.setAttachment(attachment);
            imageAttachementVO.setAttachmentBase64(base64EncoderImg);
            return  imageAttachementVO;
    }
}
